package com.lyun.config;

import com.lyun.constants.RabbitMQConstants;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

@Configuration
public class RabbitMQConfig implements BeanPostProcessor {

    /**
     * 创建交换机和队列用的rabbitAdmin对象
     */
    @Resource
    private RabbitAdmin rabbitAdmin;

    /**
     * 初始化rabbitAdmin对象
     */
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        // 只有设置为 true，spring 才会加载 RabbitAdmin 这个类
        rabbitAdmin.setAutoStartup(true);
        return rabbitAdmin;
    }

    /**
     * 实例化bean后，也就是Bean的后置处理器
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //创建交换机
        rabbitAdmin.declareExchange(rabbitmqLoveValueDirectExchange());
        //创建队列
        rabbitAdmin.declareQueue(rabbitmqLoveValueDirectQueue());
        return null;
    }

    /**
     * 定义LoveValue的交换机
     * 参数：交换机名称、是否持久化、当没有queue与其绑定时是否自动删除
     */
    @Bean
    public DirectExchange rabbitmqLoveValueDirectExchange() {
        //Direct交换机
        return new DirectExchange(RabbitMQConstants.LOVE_VALUE_EXCHANGE_NAME, true, false);
    }

    /**
     * 定义LoveValue的插入队列
     * 2、durable: 是否持久化
     * 3、exclusive: 是否独享、排外的。如果设置为true，定义为排他队列。则只有创建者可以使用此队列。也就是private私有的。
     * 4、autoDelete: 是否自动删除。也就是临时队列。当最后一个消费者断开连接后，会自动删除。
     */
    @Bean
    public Queue rabbitmqLoveValueDirectQueue() {
        return new Queue(RabbitMQConstants.LOVE_VALUE_INSERT_QUEUE_NAME, true, false, false);
    }

    /**
     * 绑定LoveValue的交换机和LoveValue插入队列 KEY为 常量 RabbitMQConstants.LOVE_VALUE_INSERT_KEY
     */
    @Bean
    public Binding loveValueBindDirect() {
        //链式写法，绑定交换机和队列，并设置匹配键
        return BindingBuilder
                //绑定队列
                .bind(rabbitmqLoveValueDirectQueue())
                //到交换机
                .to(rabbitmqLoveValueDirectExchange())
                //并设置匹配键 KEY
                .with(RabbitMQConstants.LOVE_VALUE_INSERT_KEY);
    }

}